import mqtt from "mqtt/dist/mqtt"
// import store from '@/store';

export let is_connected = false;

// 运行时可变配置（持久化 host/port，可选 protocol 和 path）
let runtimeMqttConfig = (() => {
	const saved = uni.getStorageSync('mqttConfig') || {};
	return {
		host: saved.host || '192.168.3.7',
		port: saved.port || '8083',
		protocol: saved.protocol || 'wx', // 小程序场景下默认 wx，可按需切换为 ws/wss
		path: saved.path || '/mqtt',
		username: saved.username || '',
		password: saved.password || ''
	};
})();

// 生成 Broker URL（兼容 protocol/path 配置）
function buildBrokerUrl(cfg = runtimeMqttConfig) {
	const { protocol, host, port, path } = cfg;
	return `${protocol}://${host}:${port}${path || ''}`;
}

// MQTT 服务配置
let MQTT_BROKER_URL = buildBrokerUrl();
let MQTT_OPTIONS = {
	clientId: `uniapp_${Math.random().toString(16).substr(2, 8)}`,
	username: runtimeMqttConfig.username,
	password: runtimeMqttConfig.password,
	keepalive: 3000,
	clean: true,
	reconnectPeriod: 1000
};

export let client = null;
let isConnecting = false;

// 已注册的回调：pattern -> Set<callback>
const topicCallbackMap = new Map();
// 希望保持的订阅集合（用于重连后恢复）：pattern -> qos
const desiredSubscriptions = new Map();

/**
* 检查目标 topic 是否匹配订阅的 pattern（支持 + 和 # 通配符）
* @param {string} pattern - 订阅的主题模式（如 "rtk/base_station/+" 或 "device/#"）
* @param {string} topic - 实际收到的消息主题
* @returns {boolean} - 是否匹配
*/
function isTopicMatch(pattern, topic) {
	if (pattern === topic) return true;
	const patternParts = pattern.split('/');
	const topicParts = topic.split('/');

	for (let i = 0, j = 0; i < patternParts.length && j < topicParts.length; i++, j++) {
		const p = patternParts[i];
		const t = topicParts[j];
		if (p === '#') {
			// # 必须是最后一层，匹配剩余所有部分
			return i === patternParts.length - 1;
		}
		if (p === '+') {
			continue; // 匹配任意单层
		}
		if (p !== t) {
			return false;
		}
	}

	// 处理末尾为 # 的情况或完全比对长度一致
	const lastIsHash = patternParts[patternParts.length - 1] === '#';
	return lastIsHash || patternParts.length === topicParts.length;
}

export function connectMqtt(url = MQTT_BROKER_URL) {
	if (client && client.connected) return Promise.resolve(client);
	if (isConnecting) return new Promise((resolve) => {
		const check = setInterval(() => {
			if (client && client.connected) {
				clearInterval(check);
				resolve(client);
			}
		}, 100);
	});

	isConnecting = true;
	client = mqtt.connect(url, MQTT_OPTIONS);
	console.info('connectMqtt');

	return new Promise((resolve, reject) => {
		client.once('connect', () => {
			console.log('MQTT connected');
			is_connected = true;
			isConnecting = false;
			// 重连后恢复订阅
			desiredSubscriptions.forEach((qos, topic) => {
				client.subscribe(topic, { qos }, (err) => {
					if (err) console.warn(`重连后订阅失败: ${topic}`, err);
					else console.log(`重连后已订阅: ${topic}`);
				});
			});
			resolve(client);
		});

		client.on('message', (topic, message) => {
			// console.log(`收到消息 - 主题: ${topic}, 内容: ${message.toString()}`);
			// 精确匹配
			const exact = topicCallbackMap.get(topic);
			if (exact) exact.forEach(cb => cb(topic, message));
			// 通配符匹配
			topicCallbackMap.forEach((callbacks, pattern) => {
				if (pattern !== topic && isTopicMatch(pattern, topic)) {
					callbacks.forEach(cb => cb(topic, message));
				}
			});
		});

		client.on('error', (err) => {
			console.error('❌ MQTT 连接错误:', err);
			if (isConnecting) {
				isConnecting = false;
				reject(err);
			}
		});
		client.on('close', () => {
			handleDisconnection('MQTT 连接已断开');
		});
		client.on('reconnect', () => {
			console.log('🔄 MQTT 正在尝试重连...');
		});
		// client.on('offline', () => handleDisconnection('MQTT 客户端处于离线状态'));
		client.on('disconnect', () => handleDisconnection('MQTT disconnect'));
	});
}

// 简单的主题匹配函数，支持 + 和 #
// const matchTopic = (pattern, topic) => {
// 	const patternParts = pattern.split('/');
// 	const topicParts = topic.split('/');

// 	if (patternParts.length !== topicParts.length) return false;

// 	for (let i = 0; i < patternParts.length; i++) {
// 		const p = patternParts[i];
// 		const t = topicParts[i];

// 		if (p === '+') {
// 			continue; // 匹配任意单个部分
// 		} else if (p === '#') {
// 			return true; // # 可以匹配剩余所有部分
// 		} else if (p !== t) {
// 			return false;
// 		}
// 	}

// 	return true;
// };

function handleDisconnection(message) {
	console.warn(message);
	is_connected = false;
}

export function registerCallback(topic, callback) {
	if (!topicCallbackMap.has(topic)) topicCallbackMap.set(topic, new Set());
	topicCallbackMap.get(topic).add(callback);
}

// export function unregisterCallback(topic, callback) {
// 	const callbacks = topicCallbackMap.get(topic);
// 	if (callbacks) {
// 		const index = callbacks.indexOf(callback);
// 		if (index > -1) callbacks.splice(index, 1);
// 	}
// }
export function unregisterCallback(topic, callback) {
	if (topicCallbackMap.has(topic)) {
		const callbacks = topicCallbackMap.get(topic);
		const removed = callbacks.delete(callback);
		if (removed && callbacks.size === 0) {
			topicCallbackMap.delete(topic);
			console.log(`已删除空的主题条目: ${topic}`);
		}
	}
}

export function publishMessage(topic, message) {
	if (is_connected && client) {
		client.publish(
			topic,
			message, {
				qos: 0,
				retain: false,
			},
			(err) => {
				if (err) {
					console.error('❌ 发布消息失败:', err);
				} else {
					console.log(`📤 消息已发布到 ${topic}: ${message}`);
				}
			}
		);
		return true; // 已尝试发送
	} else {
		// 触发连接，但不保证本次发送
		connectMqtt().catch(() => {});
		warnAndToast('MQTT 未连接，发布消息失败');
		return false; // 未连接，未发送
	}
}

export function subscribe(topic, callback) {
	// 记录期望订阅（默认 qos 0）
	desiredSubscriptions.set(topic, 0);
	if (callback && typeof callback === 'function') registerCallback(topic, callback);

	if (client && client.connected) {
		client.subscribe(topic, { qos: 0 }, (err) => {
			if (!err) {
				console.log(`成功订阅: ${topic}`);
			} else {
				console.error(`订阅失败: ${topic}`, err);
			}
		});
	} else {
		// 未连接则尝试连接，连接成功后会统一恢复订阅
		connectMqtt().catch(() => {});
	}
}

export function unsubscribe(topic, callback) {
	if (client && client.connected) {
		client.unsubscribe(topic, (err) => {
			if (!err) {
				unregisterCallback(topic, callback);
				console.log(`已取消订阅: ${topic}`);
			} else {
				console.error(`取消订阅失败: ${topic}`, err);
			}
		});
	} else {
		console.warn(`MQTT 未连接，无法取消订阅: ${topic}`);
	}
	// 无论连接与否，从期望订阅集中移除
	desiredSubscriptions.delete(topic);
}

export function disconnectMQTT() {
	if (client && client.connected) {
		client.end(true, () => {
			console.log('Old client connection gracefully closed');
		});
	} else {
		console.warn('MQTT 未连接，无需断开');
	}
}

function warnAndToast(message) {
	console.warn(message);
	uni.showToast({
		title: message,
		icon: 'none'
	});
}

// 配置相关 API
export function setMqttConfig(partial) {
	runtimeMqttConfig = { ...runtimeMqttConfig, ...partial };
	uni.setStorageSync('mqttConfig', runtimeMqttConfig);
	MQTT_BROKER_URL = buildBrokerUrl(runtimeMqttConfig);
	MQTT_OPTIONS = {
		...MQTT_OPTIONS,
		username: runtimeMqttConfig.username || '',
		password: runtimeMqttConfig.password || ''
	};
}

export function getMqttConfig() {
	return { ...runtimeMqttConfig, url: buildBrokerUrl(runtimeMqttConfig) };
}